封裝就是將物件(Class) 內部的資料隱藏起來, 只能透過物件(Class) 本身自己存取內部的欄位(field), 屬性(propery) 或者方法(function) , 這些內部的細節資料或者方法(function)內的邏輯隱藏起來, 其他物件不需要也無法瞭解此物件的內部細節, 也不能存取這些資料.
換句話說, 對這個物件(Class) 外面使用者只需要理解它的公開方法就好, 不需要了解裡面內部的構造.
在JavaScript 中想要封裝Person 的name 屬性,
function Person() {
this._name = "flash";
}
但是在Javascript 世界裡沒有分私有或公開成員的設計, 目前比較簡單常見的作法, 就是在私有成員(或方法)的名稱前面, 加上下底線符號 "_", 用來表示這是私有的(private)成員, 這只是由程式開發者自行規定撰寫上的區分差別, 與語言本身特性無關.
對Javascript 語言來說, 成員名稱前有沒有底線符號 _, 都是視為一樣的變數, 至於要如何保護這些私有成員, 就靠程式設計者自己了.
所以在Javascript 一旦你這樣使用
var a = new Person();
console.log(a._name);
在VSCode 編輯器編輯這段程式碼的時候, 不會彈出警告訊息, 執行時期也不會噴例外存取錯誤.
在Typescript 世界裡卻很簡單, 只需要在成員名稱前面加上 private 關鍵字
class Person {
private name: string = "flash";
public getName(): string {
return this.name;
}
}
如此一來, 當我們試圖在Typescript 裡面
var a = new Person();
console.log(a.name);
VSCode 編輯器馬上就會告訴你這段程式碼有問題, 而且也不會讓你編譯成功, 達到保護物件(Class)內部目的.
多型就是相同名稱的方法(function), 傳入不同的參數, 會執行不同的動作.
Javascript 不支援成員方法參數的多型, 只能override
function Person() {
this.show = function() {
console.log("阿..");
}
}
function Cat() {
this.prototype = Person;
this.prototype();
this.show = function() {
console.log("喵..");
}
}
function show(animal) {
animal.show();
}
var a = new Person();
var b = new Cat();
show(a);
show(b);
在這裡Cat 繼承Person 的方法是用
this.prototype = Person; this.prototype();
但如果子類別(Class) 還想執行父類別(Class)中被 override 的方法時, 則可以修改一下prototype 繼承的做法
var Person = function() {
this.show = function() {
console.log("阿..");
}
}
Person.prototype = Person;
var Cat = function() {
Person.call(this);
this.show = function() {
this.superClass.show.call(this);
console.log('喵...');
};
};
Cat.prototype = new Person();
Cat.prototype.superClass = new Person();
function show(animal) {
animal.show();
}
var a = new Person();
var b = new Cat();
show(a);
show(b);
你看你看, 是不是超麻煩的? 在Typescript 世界裡不用這麼麻煩, 只需在Cat Class 用相同一個方法名稱, 它就會自動override
class Person {
show(): void {
console.log("阿...");
}
}
class Cat extends Person {
show(): void {
console.log("喵...");
}
}
然後假設你也希望Cat 子類別要呼叫Person 父類別的show 方法, 也只需要這樣寫
class Cat extends Person {
show(): void {
super.show();
}
}
一個字 super 就可以搞定呼叫父類別這件事.
多載就是有多個相同名稱的方法(function), 但是每一個參數的型態和數量不同, 這些方法就構成了方法的多載.
這裡有一個方法多載的例子, (注意這不是Javascript 也不是Typescript), 下面是C# 語言程式碼片段
public void show(string name) {
console.log("Hello " + name);
}
public void show(string name, int amount) {
console.log("Hello " + name + " money=" + amount);
}
Javascript 世界裡不支援多載(Overloading), 但是你可以用下面方式來模擬上述的多載例子
function show(name, amount) {
if( amount == undefined ) {
console.log("Hello " + name);
return;
}
console.log("Hello " + name + " money=" + amount);
}
你可以發現Javascript 是利用參數檢查是不是沒傳送的方式, 來模擬達到多載.